package de.arnebachmann.maven;


import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.List;

/**
 * Goal which creates 'index.apt' files under ${siteDirectory} from the information contained in all subdirs' *.apt files.
 *
 * @goal aptindexes
 * 
 * @phase pre-site
 * @aggregator true
 */
public class AptDirsMojo extends AbstractMojo {
    
    /**
     * Location of the input dir.
     * @parameter default-value="${basedir}/apt"
     * @required
     */
    private File inputDirectory;
    
    /**
     * If true, erase existing index.apt files. Default: false (manually created indexes are kept).
     * @parameter default-value=false
     * @required
     */
    private boolean overwriteIndexes;
    
    /**
     * Number of index.apt created.
     */
    private int created = 0;
    
    /**
     * Number of index.apt skipped due to overwrite = false.
     */
    private int skipped = 0;

    /**
     * Main entry point for Mojo execution.
     */
    public void execute() throws MojoExecutionException {
        getLog().info("Creating APT indexes...");

        final File inputDir = inputDirectory;
        if (!inputDir.exists()) {
            throw new MojoExecutionException("Input directory '" + inputDir.getAbsolutePath() + "'doesn't exist");
        }
        
        final boolean overwrite = overwriteIndexes;
        if (overwrite) {
            getLog().info("Overwriting existing 'index.apt' resources.");
        }
        recurseInto(inputDirectory, overwrite);
        getLog().info("Finished creating " + Integer.toString(created) + " APT indexes, skipping " + Integer.toString(skipped) + " existing indexes.");
    }
    
    /**
     * Recurse into subdirs, on leafs create apt index where applicable.
     * @param aDir The dir to recurse into (starting with "." = siteDirectory)
     * @param overwrite If existing index.apt should be overwritten
     * @return If this dir has a index.apt (either created or existing)
     */
    private boolean recurseInto(final File aDir, final boolean overwrite) {
        // find all subdirs
        final File[] list = aDir.listFiles();
        final List<File> dirs = new ArrayList<File>();
        for (final File file: list) {
            if (file.isDirectory() && file.canRead()) {
                dirs.add(file);
            }
        }
        // find all subdirs with any apt docs
        final List<String> found = new ArrayList<String>();
        for (final File dir: dirs) {
            if (recurseInto(dir, overwrite)) { // if returning true, then it has apt files in it
                found.add(dir.getName());
            }
        }
        // find all apt files
        final List<File> files = new ArrayList<File>();
        for (final File file: list) {
            if (file.getName().toLowerCase().endsWith(".apt") && file.canRead()) {
                files.add(file);
            }
        }
        final boolean anyThing = (found.size() > 0) || (files.size() > 0);
        if (!anyThing) {
            return false;
        }
        // create or overwrite index.apt for subdirs found and files found
        final File index = new File(aDir, "index.apt");
        if (index.exists()) {
            if (overwrite) {
                getLog().info("Overwriting existing 'index.apt' in '" + aDir.getName() + "'");
            } else {
                skipped += 1;
            }
        }
        if (!index.exists() || overwrite) {
            created += 1;
            try {
                final FileWriter fw = new FileWriter(index);
                fw.write(" ---\n " + aDir.getName() + "\n ---\n\n");
                fw.write(aDir.getName() + "\n\n");
                if (found.size() > 0) {
                    fw.write("* Contents\n\n");
                    for (final String f: found) {
                        fw.write(" * {{{" + f + "/index.html}[" + f + "]}}\n\n");
                    }
                }
                if (files.size() > 0) {
                    for (final File f: files) {
                        try {
                            final LineNumberReader lnr = new LineNumberReader(new FileReader(f));
                            lnr.readLine(); // should be ' ---'
                            final String name = lnr.readLine().trim(); // should be the title
                            lnr.close();
                            fw.write(" * {{{" + f.getName().substring(0, f.getName().length() - 3) + "html}" + name + "}}\n\n");
                        } catch (final IOException e) {
                            getLog().error("Error reading APT title from file '" + f.getAbsolutePath() + "'", e);
                        }
                    }
                }
                fw.close();
            } catch (final IOException e) {
                getLog().error("Could not create 'index.apt' file in directory " + aDir.getAbsolutePath(), e);
                e.printStackTrace();
            }
        }
        return true;
    }

}
